<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        // 复习promise类的使用方法
        // 需求：延迟2s后打印1，完了之后延迟1s打印2，完了之后延迟1s打印3

        // <1> 实现方法1，使用回调嵌套的方式进行实现
        // -- 由于setTimeout是一个异步函数，若是我们顺序写下来，代码执行所呈现的效果肯定是不如人意的
        // -- 为了严格的保证代码的执行顺序，我们可以进行回调嵌套，即 在回调函数中嵌套新的函数
        // -- 这样确实可以严格保证异步函数的顺序执行，但代码的可读性也相应的变差了
        /* setTimeout(() => {
            console.log(1)
            setTimeout(() => {
                console.log(2)
                setTimeout(() => {
                    console.log(3)
                }, 1000)
            }, 1000)
        }, 2000) */

        // <2> 实现方法2， 在此之前，先讲解promise的基本使用
        // promise的基本使用
        /* const p = new Promise((resolve, reject) => {
            // resolve 和 reject表示成功、失败这两种状态，我们可以通过在promise实例时调用对应的方法来确定其状态
            // 但是需要注意的是，每次实例仅能进行一次状态确定，若存在多次，也仅取第一次
            resolve()
        })

        p.then((n1) => {
            // 状态为成功时执行
            console.log("succeed!")
        }, (n2) => {
            // 状态为失败时执行
            console.log("error")
        }) */ 
       
        // 实现方法2，使用promise链式调用消除回调地狱

        // 1 封装异步函数
        // function delay(duration, n) {
        //     return new Promise((resolve, reject) => {
        //         setTimeout(() => {
        //             // 传递参数
        //             resolve(n)
        //         }, duration)
        //     })
        // }

        // 2 调用Promise对象的then（）方法
        // -- 由于此异步不存在失败，因此不写第二个处理失败的回调函数
        // delay(2000, 1).then((n1) => {
        //     console.log(n1)
        //     return delay(1000, 2)
        // }).then((n2) => {
        //     console.log(n2)
        //     return delay(1000, 3)
        // }).then((n3) => {
        //     console.log(n3)
        // })

        // <3> 实现方法3 回调地狱的终极解决方法
        // 使用Async + Await 结合 Promise进行解决

        // 1 封装异步函数
        function delay(duration, n) {
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    resolve(n)
                }, duration)
            })
        }

        // 2 使用Async + Await进行解决
        async function log() {
            const n1 = await delay(2000, 1)
            console.log(n1)
            const n2 = await delay(1000, 2)
            console.log(n2)
            const n3 = await delay(1000, 3)
            console.log(n3)
        }

        log()




    </script>
</body>
</html>
